package com.zbkj.crmeb.store.service.impl;

import cn.hutool.core.util.StrUtil;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.merchant.admin.service.MerStoreOrderService;
import com.zbkj.crmeb.store.dao.StoreOrderGroupInfoDao;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.StoreOrderRefundRequest;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Struct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能描述: 拼团相关服务具体实现
 * @Author: wangzh
 * @Date: 2022/12/1 14:09
 */
@Service
@Slf4j
public class StoreOrderGroupInfoServiceImpl extends ServiceImpl<StoreOrderGroupInfoDao, StoreOrderGroupInfo> implements StoreOrderGroupInfoService {

    @Autowired
    private StoreProductGroupActivityService storeProductGroupActivityService;
    @Autowired
    private ChannelGroupBookingService channelGroupBookingService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private MerStoreOrderService storeOrderService;
    @Autowired
    private UserService userService;
    @Autowired
    private StoreAccountInfoService storeAccountInfoService;
    @Autowired
    private IChannelMerchantService channelMerchantService;

    /**
     * 功能描述: 拼团商品 设置拼团价以及活动时间、限购进行处理，不符合不生成订单信息 订单信息统计在生成订单中处理
     * @Param: [currentUserInfo, storeCartResponse, channelMerchant, joinPersonNumber]
     * @Return: void
     * @Author: wangzh
     * @Date: 2022/12/2 10:30
     */
    @Override
    public void dealGroupActivityProduct(User currentUserInfo, List<StoreCartResponse> storeCartResponse, ChannelMerchant channelMerchant, Integer skuId, String groupId) {
        if (storeCartResponse.get(0).getPickingId() == 0){
            StoreCartResponse cartResponse = storeCartResponse.get(0);
            Integer productId = cartResponse.getProductId();
            //该商户下进行中的拼团活动
            List<Integer> groupActivityIds = channelGroupBookingService.getInProgressActivityIds(channelMerchant.getId());
            //商户下没有进行中的拼团活动，不设置商品拼团价，直接返回
            if (CollectionUtils.isEmpty(groupActivityIds) && (StringUtils.isEmpty(groupId))){
                return;
            }
            // 商品sku对应的拼团价格
            log.info("商品sku对应的拼团价格前:{}，{}", skuId, groupId);
            StoreProductGroupActivity storeProductGroupActivity = storeProductGroupActivityService.getByIdAndActivityId(skuId, groupId);
            log.info("商品sku对应的拼团价格后:{}", JSONObject.toJSONString(storeProductGroupActivity));
            //没有该商品的活动信息
            if (Objects.isNull(storeProductGroupActivity)){
                return;
            }
            // 拼团信息
            ChannelGroupBooking channelGroupBooking = channelGroupBookingService.getOne(Wrappers.<ChannelGroupBooking>lambdaQuery()
                    .eq(ChannelGroupBooking::getId, storeProductGroupActivity.getActivityId())
                    .in(ChannelGroupBooking::getId, groupActivityIds)
                    .last("limit 1"));
            // 查不到活动信息，活动结束
            if (Objects.isNull(channelGroupBooking)){
                return;
            }
            cartResponse.setActivityGroupId(channelGroupBooking.getId());
            //判断商品是否限购
            if (channelGroupBooking.getPurchaseLimitType() == 1){
                //限购数量
                Integer purchaseLimitNumber = channelGroupBooking.getPurchaseLimitNumber();
                //用户购买数量
                int count = 0;
                //用户拼过的订单号
                List<Integer> orderIds = new ArrayList<>();
//                List<StoreOrderGroupInfo> storeOrderGroupInfos = getGroupOrderIds(productId, currentUserInfo.getMerId());
//                storeOrderGroupInfos.forEach(e -> {
//                    int index = Arrays.binarySearch(e.getUids().split(","), currentUserInfo.getUid().toString());
//                    if (index >= 0){
//                        orderIds.add(Integer.valueOf(e.getOrderIds().split(",")[index]));
//                    }
//                });
                // 过滤掉不是这个拼团的订单id
                orderIds = getOrderIds(groupId,currentUserInfo.getUid());
                //查询用户订单，看用户买过几件
                if (CollectionUtils.isNotEmpty(orderIds)){
                    count = storeOrderInfoService.count(Wrappers.<StoreOrderInfo>lambdaQuery()
                            .eq(StoreOrderInfo::getProductId, productId)
                            .in(StoreOrderInfo::getOrderId, orderIds));
                }
                //购买数量超过限制
                if (count + cartResponse.getCartNum() > purchaseLimitNumber) {
                    throw new CrmebException(StrUtil.format("拼团商品限制购买{}件，您还可以购买{}件", purchaseLimitNumber, purchaseLimitNumber - count));
                }
            }
            // 用户可以购买。 设置商品价格
            setGroupPrice(channelMerchant, storeProductGroupActivity, storeCartResponse);
        }
    }

    private List<Integer> getOrderIds(String groupId,Integer uid) {
        if (StringUtils.isEmpty(groupId)){
            return Collections.emptyList();
        }
        QueryWrapper<ChannelGroupBooking> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id");
        queryWrapper.eq("group_id", groupId);
        List<ChannelGroupBooking> bookingList = channelGroupBookingService.list(queryWrapper);
        List<Integer> activityIds = bookingList.stream().map(ChannelGroupBooking::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activityIds)){
            return Collections.emptyList();
        }
        List<StoreOrder> storeOrders = storeOrderService.list(
                Wrappers.<StoreOrder>lambdaQuery().in(StoreOrder::getActivityId, activityIds)
                        .eq(StoreOrder::getUid, uid));
        if (CollectionUtils.isNotEmpty(storeOrders)){
            return storeOrders.stream().map(StoreOrder::getId).collect(Collectors.toList());
        }
        return Collections.emptyList();

    }

    @Override
    @Async("taskExecutor")
    public Boolean startGroup(StoreOrder storeOrder, List<StoreOrderInfo> storeOrderInfoList) {
        //拼团订单不允许从购物车结算，按理来说这里只会有一个商品id
        Integer productId = storeOrderInfoList.stream().map(StoreOrderInfo::getProductId).distinct().collect(Collectors.toList()).get(0);
        ChannelGroupBooking channelGroupBooking = channelGroupBookingService.getById(storeOrder.getActivityGroupId());
        StoreOrderGroupInfo groupInfo = this.getOne(Wrappers.<StoreOrderGroupInfo>lambdaQuery()
                .eq(StoreOrderGroupInfo::getProductId, productId)
                .eq(StoreOrderGroupInfo::getStatus, 0)
                .last("limit 1"));
        // 查询不到该商品拼团信息，开一个团 同一个用户，再次下单，给用户再开一个团
        if (Objects.isNull(groupInfo) || Arrays.asList(groupInfo.getUids().split(",")).contains(storeOrder.getUid().toString())){
            ChannelMerchant channelMerchant = channelMerchantService.getById(storeOrder.getMerId());
            StoreOrderGroupInfo info = new StoreOrderGroupInfo();
            info.setOrderIds(storeOrder.getId().toString())
                    .setProductId(productId)
                    .setProductGroupNumber(channelGroupBooking.getJoinPersonNumber())
                    .setUids(storeOrder.getUid().toString())
                    .setStatus(false)
                    .setMerId(storeOrder.getMerId());
            boolean save = this.save(info);
            storeOrderService.update(Wrappers.<StoreOrder>lambdaUpdate()
                    .eq(StoreOrder::getId, storeOrder.getId())
                    .set(StoreOrder::getActivityGroupId, info.getId())
                    .set(Objects.equals(channelMerchant.getAutoPush(), 1), StoreOrder::getPushStatus, 3));
            return save;
        }

        groupInfo.setOrderIds(groupInfo.getOrderIds() + "," + storeOrder.getId());
        groupInfo.setUids(groupInfo.getUids() + "," + storeOrder.getUid());
        // 拼团人数已经满足，设置拼团状态，并且订单状态转换为待发货
        if (groupInfo.getOrderIds().split(",").length == channelGroupBooking.getJoinPersonNumber()){
            groupInfo.setStatus(true);
            ChannelMerchant channelMerchant = channelMerchantService.getById(groupInfo.getMerId());
            List<StoreOrderInfo> list = storeOrderInfoService.list(Wrappers.<StoreOrderInfo>lambdaQuery()
                    .in(StoreOrderInfo::getOrderId, Arrays.asList(groupInfo.getOrderIds().split(","))));
            Map<Integer, StoreOrderInfo> storeOrderInfos = list.stream().collect(Collectors.toMap(StoreOrderInfo::getId, e -> e));
            // 给所有子订单确认 默认选择商家自主发货
            List<Integer> ids = new ArrayList<>();
            List<Integer> subIds = new ArrayList<>();
            for (Integer i : storeOrderInfos.keySet()){
                storeOrderService.update(Wrappers.<StoreOrder>lambdaUpdate()
                        .eq(StoreOrder::getId, storeOrderInfos.get(i).getOrderId())
                        .set(StoreOrder::getPushStatus, 0));
                // 自建商品，记录子订单id，统一变为待发货
                if (Objects.equals(storeOrderInfos.get(i).getIsEurope(), 1)){
                    // 主订单
                    ids.add(storeOrderInfos.get(i).getOrderId());
                    // 子订单
                    subIds.add(i);
                } else {
                    if (Objects.equals(channelMerchant.getAutoPush(), 0)){
                        storeOrderService.independentDelivery(i, true, storeOrder.getMerId(), null);
                    }
                }
            }
            // 将自建商品状态改变为待发货
            if (CollectionUtils.isNotEmpty(subIds)){
                storeOrderInfoService.update(Wrappers.<StoreOrderInfo>lambdaUpdate()
                        .in(StoreOrderInfo::getId, subIds)
                        .set(StoreOrderInfo::getStatus, 1));
                if (CollectionUtils.isNotEmpty(ids)){
                    storeOrderService.update(Wrappers.<StoreOrder>lambdaUpdate()
                            .in(StoreOrder::getId, ids)
                            .set(StoreOrder::getStatus, 1));
                }
            }
        }
        boolean b = this.saveOrUpdate(groupInfo);
        storeOrderService.update(Wrappers.<StoreOrder>lambdaUpdate()
                .eq(StoreOrder::getId, storeOrder.getId())
                .set(StoreOrder::getActivityGroupId, groupInfo.getId()));
        return b;
    }

    /**
     * 功能描述: 通过商品id获取开团信息
     * @Param: [productId]
     * @Return: java.util.List<java.lang.Integer>
     * @Author: wangzh
     * @Date: 2022/12/2 13:01
     */
    @Override
    public List<StoreOrderGroupInfo> getGroupOrderIds(Integer productId, Integer merId) {
        return this.list(Wrappers.<StoreOrderGroupInfo>lambdaQuery()
                .eq(StoreOrderGroupInfo::getProductId, productId)
                .eq(StoreOrderGroupInfo::getMerId, merId));
    }

    /**
     * @Description: 返回商品拼团用户头像与名称
     * @param productId
     * @Return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     * @Author: wangzh
     * @Date: 2022/12/4 21:13
     */
    @Override
    public List<Map<String, Object>> getGroupOrderInfo(Integer productId, Integer merId) {
        List<Map<String, Object>> response = new ArrayList<>();
        List<StoreOrderGroupInfo> storeOrderGroupInfoList = getGroupOrderIds(productId, merId);
        List<String> uids = Arrays.asList(storeOrderGroupInfoList.stream().map(StoreOrderGroupInfo::getUids).collect(Collectors.joining(",")).split(","));
        if (CollectionUtils.isEmpty(uids)){
            return null;
        }
        List<User> users = userService.list(Wrappers.<User>lambdaQuery()
                .in(User::getUid, uids));
        // uid与用户实体对应
        Map<Integer, User> uidToUser = users.stream().collect(Collectors.toMap(User::getUid, e -> e));
        for (StoreOrderGroupInfo storeOrderGroupInfo : storeOrderGroupInfoList){
            Map<String, Object> map = new HashMap<>();
            map.put("id", storeOrderGroupInfo.getId());
            for (String id : storeOrderGroupInfo.getUids().split(",")){
                User user = uidToUser.get(Integer.valueOf(id));
                if (Objects.isNull(map.get("image"))){
                    map.put("image", user.getAvatar());
                } else {
                    map.put("image", map.get("image") + user.getAvatar());
                }
                if (Objects.isNull(map.get("username"))){
                    map.put("username", user.getNickname());
                } else {
                    map.put("username", map.get("username") + user.getNickname());
                }
            }
            response.add(map);
        }
        return response;
    }

    /**
     * 功能描述: 超时自动退款定时任务
     * @Param: []
     * @Return: void
     * @Author: wangzh
     * @Date: 2022/12/5 14:07
     */
    @Override
    public void overtimeAutoRefund() {
        // 所有支付成功且状态为待确认的拼团订单信息
        List<StoreOrder> storeOrders = storeOrderService.list(Wrappers.<StoreOrder>lambdaQuery()
                .isNotNull(StoreOrder::getActivityGroupId)
                .eq(StoreOrder::getPaid, 1)
                .eq(StoreOrder::getStatus, 6));
        // 已经退款过的订单
        List<String> alreadyRefundOrderIds = new ArrayList<>();
        List<StoreAccountInfo> list = storeAccountInfoService.list(Wrappers.<StoreAccountInfo>lambdaQuery()
                .eq(StoreAccountInfo::getOperateId, 0));
        if (CollectionUtils.isNotEmpty(list)){
            alreadyRefundOrderIds = list.stream().map(StoreAccountInfo::getOrderId).collect(Collectors.toList());
        }
        for (StoreOrder storeOrder : storeOrders){
            boolean refund = false;
            // 拼团订单超过72小时
            if (DateUtils.addHours(storeOrder.getCreateTime(), 72).before(new Date())){
                List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(Wrappers.<StoreOrderInfo>lambdaQuery()
                        .eq(StoreOrderInfo::getOrderId, storeOrder.getId()));
                for (StoreOrderInfo storeOrderInfo : storeOrderInfos){
                    // 已经退款，跳过
                    if (alreadyRefundOrderIds.contains(storeOrderInfo.getChildOrderNumber())){
                        refund = true;
                        continue;
                    }
                    StoreOrderRefundRequest request = new StoreOrderRefundRequest();
                    request.setOrderId(storeOrderInfo.getId()).setAmount(storeOrderInfo.getPayPrice()).setType(1);
                    log.info(StrUtil.format("--------------------------- 拼团订单{}，超过72小时未拼团成功，系统开始自动退款: 退款金额{} ---------------------------", storeOrder.getId(), storeOrderInfo.getPayPrice()));
                    if (storeOrderInfo.getIsEurope() != 1){
                        request.setType(2);
                    }
                    storeOrderService.refund(request);
                }
                if (refund){
                    continue;
                }
                // 退款成功，消除改订单的拼团信息
                removeGroupInfo(storeOrder);
            }
        }
    }

    private void setGroupPrice(ChannelMerchant channelMerchant, StoreProductGroupActivity storeProductGroupActivity, List<StoreCartResponse> storeCartResponse){
        for (StoreCartResponse storeCart : storeCartResponse){
            if (storeCart.getProductInfo().getAttrInfo().getSourceSkuId().equals(storeProductGroupActivity.getSourceSkuId())){
                // TODO DIDIOK PRICE -10
                storeCart.setTruePrice(storeProductGroupActivity.getPackagePrice());
                storeCart.setPackagePrice(storeProductGroupActivity.getPackagePrice());
                if (channelMerchant.getAppletType() == 1){
                    storeCart.setTruePrice(storeCart.getTruePrice().subtract(storeCart.getTaxAndSecondPrice()));
                }
            }
        }
    }

    @Async("taskExecutor")
    public void removeGroupInfo(StoreOrder storeOrder){
        StoreOrderGroupInfo one = this.getById(storeOrder.getActivityGroupId());
        List<Integer> orderIds = Arrays.stream(one.getOrderIds().split(",")).map(Integer::valueOf).collect(Collectors.toList());
        orderIds.remove(storeOrder.getId());
        List<Integer> uids = Arrays.stream(one.getUids().split(",")).map(Integer::valueOf).collect(Collectors.toList());
        uids.remove(storeOrder.getUid());
        // 该拼团订单为0 删除拼团信息
        if (org.apache.commons.collections.CollectionUtils.isEmpty(orderIds)){
            this.removeById(one.getId());
        } else {
            one.setOrderIds(orderIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
            one.setUids(uids.stream().map(String::valueOf).collect(Collectors.joining(",")));
            this.updateById(one);
        }
    }

}
